﻿using DL.Input;
using DL.Tools;
using UnityEngine;

namespace DL.Characters.Camera
{
    public class TP_CameraController : MonoBehaviour
    {
        enum LerpMode
        {
            Line,
            Slerp
        }
        
        //相机设置
        private Transform m_LookPlayer;
        private Transform m_LookEnemy;
        private Transform m_CurrentLookTarget;

        public Transform LookPlayer
        {
            get => m_LookPlayer;
            set => m_LookPlayer = value;
        }
        public Transform LookEnemy
        {
            get => m_LookEnemy;
            set => m_LookEnemy = value;
        }

        //参数设置
        [SerializeField, Tooltip("相机灵敏度")]
        private Vector2 cameraControlSpeed = new Vector2(.5f, .5f);
        [SerializeField, Tooltip("相机Y轴最大仰角")] 
        private Vector2 clampAngle = new Vector2(-40, 70);
        [SerializeField, Tooltip("相机相对于目标的偏移量")]
        private float targetPositionOffset = -0.8f;
        [SerializeField, Tooltip("相机旋转平滑度")] 
        private float rotationSmoothSpeed = 2;
        [SerializeField, Tooltip("相机跟随目标平滑度")] 
        private float cameraFollowSmoothSpeed = 10;

        [SerializeField, Tooltip("插值方式")] 
        private LerpMode lerpMode = LerpMode.Line;
        
        private Vector3 m_Input;
        private Vector3 m_CameraRotation;
        private bool m_Init = false;
        private void Awake()
        {
            m_LookPlayer = GameObject.FindWithTag("CameraLookTarget").transform;
            m_Init = true;
        }

        private void Start()
        {
            Cursor.visible = false;
            Cursor.lockState = CursorLockMode.Locked;
            m_CurrentLookTarget = m_LookPlayer;
        }

        private void FixedUpdate()
        {
            if(!m_Init) return;
            SetCameraInput();
        }

        private void LateUpdate()
        {
            if(!m_Init) return;
            UpdateCameraRotation();
            UpdateCameraPosition();
        }

        private void SetCameraInput()
        {
            m_Input.y += CharacterInputSystem.Inst.CameraLook.x * cameraControlSpeed.x;
            m_Input.x -= CharacterInputSystem.Inst.CameraLook.y * cameraControlSpeed.y;
            m_Input.x = Mathf.Clamp(m_Input.x, clampAngle.x, clampAngle.y);
        }

        private void UpdateCameraRotation()
        {
            if (lerpMode == LerpMode.Line)
            {
                m_CameraRotation = Vector3.Lerp(m_CameraRotation, m_Input,
                    DevelopmentToos.UnTetheredLerp(rotationSmoothSpeed));
            }
            else
            {
                m_CameraRotation = Vector3.Slerp(m_CameraRotation, m_Input,
                    DevelopmentToos.UnTetheredLerp(rotationSmoothSpeed));
            }
            transform.eulerAngles = m_CameraRotation;
            m_LookPlayer.eulerAngles = m_Input;
        }

        private void UpdateCameraPosition()
        {
            Vector3 position = ((m_CurrentLookTarget == m_LookEnemy)
                ? (m_CurrentLookTarget.position + (m_CurrentLookTarget.up * .7f))
                : m_CurrentLookTarget.position + (-transform.forward * targetPositionOffset));
            if (lerpMode == LerpMode.Line)
            {
                transform.position = Vector3.Lerp(transform.position, position,
                    DevelopmentToos.UnTetheredLerp(cameraFollowSmoothSpeed));
            }
            else
            {
                transform.position = Vector3.Slerp(transform.position, position,
                    DevelopmentToos.UnTetheredLerp(cameraFollowSmoothSpeed));
            }
        }
    }
}